package com.leemon.mall.admin.security;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.leemon.mall.common.util.CacheManagerUtil;
import com.leemon.mall.security.constants.SecurityConstants;
import com.leemon.mall.security.dto.MySysUser;
import com.leemon.mall.sys.constant.SysConstant;
import com.leemon.mall.sys.dao.SysMenuMapper;
import com.leemon.mall.sys.dao.SysUserMapper;
import com.leemon.mall.sys.model.SysMenu;
import com.leemon.mall.sys.model.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author limenglong
 * @create 2019-09-09 17:16
 * @desc
 **/
@Service
public class SysUserDetailsService implements UserDetailsService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private CacheManagerUtil cacheManagerUtil;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        MySysUser sysUser = cacheManagerUtil.getCache(SecurityConstants.SECURITY_SYS_USER, username);
        if (ObjectUtil.isNotEmpty(sysUser)) {
            return sysUser;
        }
        MySysUser userDetails = getUserDetails(username);
        //把security用户放入缓存
        cacheManagerUtil.putCache(SecurityConstants.SECURITY_SYS_USER, username, userDetails);
        return userDetails;
    }


    private MySysUser getUserDetails(String username) {
        SysUser sysUser = sysUserMapper.selectByUserName(username);

        if (ObjectUtil.isEmpty(sysUser)) {
            throw new UsernameNotFoundException("用户不存在");
        }

        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(getUserPermissions(sysUser.getUserId()).toArray(new String[0]));

        //构造security用户
        return new MySysUser(sysUser.getUserId(), sysUser.getShopId(), sysUser.getUsername(), sysUser.getPassword()
                , sysUser.getStatus() == 1, true, true, true, authorityList
        );
    }

    //获取用户权限
    private Set<String> getUserPermissions(Long userId) {
        List<String> permsList = new ArrayList<>();

        //超级管理员用户，获取所有权限
        if (userId == SysConstant.SUPER_ADMIN_ID) {
            List<SysMenu> sysMenus = sysMenuMapper.selectList(Wrappers.emptyWrapper());
           permsList.addAll(sysMenus.stream().map(SysMenu::getPerms).collect(Collectors.toList()));
        } else {
            permsList.addAll(sysUserMapper.queryAllPerms(userId)) ;
        }

        Set<String> permSet = permsList.stream().flatMap((perms) -> {
            if (StringUtils.isBlank(perms)) {
                return null;
            }
            return Arrays.stream(perms.trim().split(","));
        }).collect(Collectors.toSet());

        return permSet;
    }
}
